package trying;

import java.util.Arrays;
import java.util.Collections;

public class Intern {
    public static void main(String[] args) {

        /**
         * String.intern()方法返回字符串对象的规范化表示形式。返回的字符串取自具有唯一字符串的池(一般是常量池)
         * 建议直接String str = "XX" 进行定义，这样如果常量池没有XX就会把str地址作为引用，常用的字符串复用时提高效率，也可以使用intern方法
         * String的a+b操作会使用StringBuilder.append方法进行字符串拼接，然后使用toString方法进行返回，会造成内存消耗，这是语法糖
         * String是用final修饰的不可变类，严格来说String是个字符串常量，所以每次对String操作都会在常量池产生新的对象或者指向已有的对象
         * StringBuilder可变，底层是char[]，创建时会给一定容量的数组，之后append或者其他操作都会在原对象里变化，例如[a] --> [a,b]
         */
        String s1 = "YSZ";
        String s2 = new String("Y")+ new String("SZ");

        //false，常量池存的是s1的引用，s2.intern取常量池则指向了s1
        System.out.println(s2.intern() == s2);
        //true
        System.out.println(s2.intern() == s1);
        //false，YSZ指向的是s1的地址
        System.out.println(s2 == "YSZ");
        //true
        System.out.println(s1 == "YSZ");

        String s3 = "YSZ";
        //true，s3先找常量池，池里有这个值且引用到了s1，那s3直接指向s1
        System.out.println(s3 == s1);

        //把ZSY放到常量池，指向str4的地址
        String s4 = new String("ZSY").intern();
        String s5 = "ZSY";
        //true
        System.out.println(s5 == s4);

        String s6 = "Y";
        String s7 = "SZ";
        String s8 = s6 + s7;
        //false，s6+s7实际是用StringBuilder.append完成，不是同个对象了
        System.out.println(s1 == s8);

        System.out.println(s5.hashCode());
        System.out.println(s4.hashCode());
    }
}
